#include<iostream>
using std::endl;
using std::cout;
using std::string;
#include<list>
using std::list;
#include <memory>
using std::unique_ptr;

//实现观察者模式
//自定义一个怪物攻击队列

//怪物抽象类
class Monster{
public:
    virtual void hitFunction(const string &name) = 0;
    virtual ~Monster(){}; //析构函数不能是纯虚函数，必须要有一个实现
};
class Goblin
:public Monster
{
public:
    void hitFunction(const string &name) override{
        cout<<"Goblin 发出了"<<name.c_str()<<" 攻击方式"<<endl;
    }
    ~Goblin()override {
        cout<<"~Goblin"<<endl;}
};
class Slime
:public Monster
{
public:
    void hitFunction(const string &name) override{
        cout<<"Slime 发出了"<<name.c_str()<<" 攻击方式"<<endl;
    }
    ~Slime()override { 
    cout<<"~Slime"<<endl;}
};

class HitTeam{
public:
    virtual void addTeam(Monster*) = 0;
    virtual void deleTeam(Monster* ) = 0;
    virtual ~HitTeam() {};
    virtual void notify() = 0;
};

class myHitTeam
:public HitTeam
{
public:
    void addTeam(Monster*) override;
    void deleTeam(Monster*) override;
    void notify();
    ~myHitTeam() override {cout<<"~myHitTeam"<<endl;}
private:
    list<unique_ptr<Monster>> _monsterList;
};
void myHitTeam::addTeam(Monster* monster){
    //unique_ptr 
    //review 
    //uniqu_ptr 可以用移动语义 因为该智能指针已经把拷贝构造删掉了
    _monsterList.push_back(unique_ptr<Monster>(monster));
}

void myHitTeam::deleTeam(Monster*monster){
    for(auto it = _monsterList.begin();it!= _monsterList.end();++it){
        if(*it == unique_ptr<Monster>(monster)){
            _monsterList.remove(unique_ptr<Monster>(monster));
            break;
        }
    }
}
void myHitTeam::notify(){
    //全部执行攻击指令
    for(auto it = _monsterList.begin();it!= _monsterList.end();it++){
        //unique_ptr<Monster> p(new Goblin);
        //p->hitFunction("hit");
        //it->get()->hitFunction("hit");   
        (*it)->hitFunction("hit");
    }
}

void test0(){
    Goblin *g1 = new Goblin();
    Goblin *g2 = new Goblin();
    Slime  *s1 = new Slime();
    Slime  *s2 = new Slime();
    
    myHitTeam Myhit;
    Myhit.addTeam(g1);
    Myhit.addTeam(g2);
    Myhit.addTeam(s1);
    Myhit.addTeam(s2);
    Myhit.notify();
}

int main(void){
    test0();
}